package com.xzx.helloworld;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

/**
 * DiscardServerHandler继承自ChannelInboundHandlerAdapter，
 * ChannelInboundHandlerAdapter是ChannelInboundHandler的实现。
 * ChannelInboundHandler提供了各种可以覆盖的事件处理程序方法。
 * 现在，扩展ChannelInboundHandlerAdapter就足够了，而不是自己实现ChannelInboundHandler接口。
 *
 * @author xinzhixuan
 * @version 1.0
 * @date 2025/10/14 14:42
 */
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 当Channel注册到EventLoop时调用，注册时只调用一次
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelRegistered");
    }

    /**
     * 当Channel从EventLoop中注销时调用，注销时只调用一次
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelUnregistered");
    }

    /**
     * 当连接断开时会调用,在channelUnregistered()之前调用
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelInactive");
    }

    /**
     * 当连接准备就绪时会调用,在channelRegistered()方法之后调用
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelActive");
    }

    /**
     * 我们在这里重写了channelRead（）事件处理程序方法。
     * 每当从客户端接收到新数据时，将使用接收到的消息调用此方法。在本例中，接收到的消息类型为ByteBuf
     *
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("channelRead");
        ByteBuf in = (ByteBuf) msg;
//        try {
//            while (in.isReadable()) { // (1)
//                System.out.print((char) in.readByte());
//                System.out.flush();
//            }
//        } finally {
//            ReferenceCountUtil.release(msg); // (2)
//        }

         //这个低效的循环实际上可以简化为：System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII))
        try {
            System.out.println(in.toString(io.netty.util.CharsetUtil.US_ASCII));
        } finally {
            ReferenceCountUtil.release(msg); // (2)
        }


    }

    /**
     * 当ChannelRead（）方法完成时调用
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelReadComplete");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        System.out.println("userEventTriggered");
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelWritabilityChanged");
    }

    /**
     * 当Netty由于IO错误或handler处理事件时抛出的异常而引发异常时，将使用Throwable调用exceptionCaught（）事件处理程序方法。
     * 在大多数情况下，应该记录捕获的异常，并在此关闭其关联的通道
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("exceptionCaught");
        cause.printStackTrace();
    }
}
